import random
import math

import numpy as np

from data_preparation.trajectory_set import TrajectorySet
from discretization.grid import Grid


class SquareQuery:
    def __init__(self,grid:Grid):
        border = grid.get_grid_border("all")

        self.max_y = border[0]
        self.min_y = border[1]
        self.min_x = border[2]
        self.max_x = border[3]
        self.center_x = random.random() * (self.max_x - self.min_x) + self.min_x
        self.center_y = random.random() * (self.max_y - self.min_y) + self.min_y
        self.center = (self.center_x, self.center_y)
        # 计算圆心到四个边界的距离
        distance_north = self.max_y - self.center_y
        distance_south = self.center_y - self.min_y
        distance_west = self.center_x - self.min_x
        distance_east = self.max_x - self.center_x
        # 确定半径的范围
        max_radius = min(distance_north, distance_south, distance_west, distance_east)
        if max_radius <= 0:
            raise ValueError("The query region is too small")
        # 生成随机半径
        self.radius = random.random() * max_radius

    def get_origin_density(self, trajectory_set1: TrajectorySet) -> int:
        count = 0
        trajectoy_number = trajectory_set1.get_trajectory_number()
        for i in range(trajectoy_number):
            trajectory1 = trajectory_set1.give_trajectory_by_index(i)
            index_array = trajectory1.experiment_array
            for j in range(len(index_array)):
                if self.is_inside(index_array[j]):
                    count += 1
                    break;
        return count

    def get_synthetic_density(self,synthetic_trajectory:list) -> int:
        count = 0
        for i in range(len(synthetic_trajectory)):
            index_array = synthetic_trajectory[i]
            for j in range(len(index_array)):
                if self.is_inside(index_array[j]):
                    count += 1
                    break;
        return count

    def is_inside(self, point):
        distance = math.sqrt((point[0] - self.center_x) ** 2 + (point[1] - self.center_y) ** 2)
        if distance <= self.radius:
            return True
        else:
            return False



